using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace PeDALS.Tools.AZ.PSTArchive.PSTData
{
    public class PSTNode
    {
        private NBTEntry mneEntry;
        private BBTEntry mbeEntry;
        private BBTEntry mbeSubEntry;
        private PSTBlock mbBlock;
        private PSTBlock mbSubBlock;
        private List<byte[]> mlbaClearBlockList = new List<byte[]>();
        private List<byte[]> mlbaClearSubBlockList = new List<byte[]>();
        private byte[] mrgbClearDataBits;
        private char[] mrgbClearDataText;

        public PSTNode(BinaryReader brReader, bool blnUnicode, NBTEntry neEntry, List<NBTEntry> lneEntries, List<BBTEntry> lbeEntries)
        {
            mneEntry = neEntry;
            mbeEntry = lbeEntries.Find(delegate(BBTEntry beFoundEntry) { return beFoundEntry.BID == neEntry.bidData.BID; });
            mbeSubEntry = lbeEntries.Find(delegate(BBTEntry beFoundEntry) { return beFoundEntry.BID == neEntry.bidSub.BID; });
            if (mbeEntry != null)
            {
                mbBlock = new PSTBlock(brReader, blnUnicode, mbeEntry, lneEntries, lbeEntries);
            }
            if (mbeSubEntry != null)
            {
                mbSubBlock = new PSTBlock(brReader, blnUnicode, mbeSubEntry, lneEntries, lbeEntries);
            }
            List<byte[]> lbaBlockList = LoadDataByteArray(mbBlock);
            List<byte[]> lbaSubBlockList = LoadDataByteArray(mbSubBlock);
            mlbaClearBlockList = DecryptByteArrays(lbaBlockList, 0, 0x01);
            mlbaClearSubBlockList = DecryptByteArrays(lbaSubBlockList, 0, 0x01);
            long lngOffset;
            mrgbClearDataBits = new byte[0];
            foreach (byte[] baDataBytes in mlbaClearBlockList)
            {
                lngOffset = mrgbClearDataBits.Length;
                Array.Resize(ref mrgbClearDataBits, (int) (lngOffset + baDataBytes.Length));
                Array.Copy(baDataBytes, 0, mrgbClearDataBits, (int) lngOffset, baDataBytes.Length);
            }
            foreach (byte[] baSubDataBytes in mlbaClearSubBlockList)
            {
                lngOffset = mrgbClearDataBits.Length;
                Array.Resize(ref mrgbClearDataBits, (int)(lngOffset + baSubDataBytes.Length));
                Array.Copy(baSubDataBytes, 0, mrgbClearDataBits, (int)lngOffset, baSubDataBytes.Length);
            }
            int intI = 0;
            mrgbClearDataText = new char[mrgbClearDataBits.Length];
            foreach (byte bChar in mrgbClearDataBits)
            {
                mrgbClearDataText[intI] = Convert.ToChar(bChar);
                intI++;
            }
        }

        public NBTEntry NodeEntry
        {
            get { return mneEntry; }
            set { mneEntry = value; }
        }
	
        public BBTEntry BlockEntry
        {
            get { return mbeEntry; }
            set { mbeEntry = value; }
        }

        public BBTEntry BlockSubEntry
        {
            get { return mbeSubEntry; }
            set { mbeSubEntry = value; }
        }
	
        public PSTBlock Block
        {
            get { return mbBlock; }
            set { mbBlock = value; }
        }
	
        public PSTBlock SubBlock
        {
            get { return mbSubBlock; }
            set { mbSubBlock = value; }
        }

        public byte[] rgbClearDataBits
        {
            get
            {
                return mrgbClearDataBits;
            }
            set
            {
                mrgbClearDataBits = value;
            }
        }

        private List<byte[]> LoadDataByteArray(PSTBlock pblBlock)
        {
            List<byte[]> lbaResults = new List<byte[]>();
            List<byte[]> lbaSubResults = new List<byte[]>();

            if (pblBlock != null)
            {
                if (pblBlock.rgbDataBits != null)
                {
                    lbaResults.Add(pblBlock.rgbDataBits);
                }
                foreach (PSTBlock pblSubBlock in pblBlock.lpbBlocks)
                {
                    lbaSubResults = LoadDataByteArray(pblSubBlock);
                    foreach (byte[] baDataBytes in lbaSubResults)
                    {
                        lbaResults.Add(baDataBytes);
                    }
                }
            }
            return lbaResults;
        }

        private List<byte[]> DecryptByteArrays(List<byte[]> lbaBlock, int intbid, byte bAlgorithm)
        {
            List<byte[]> lbaResults = new List<byte[]>();
            foreach (byte[] baEntry in lbaBlock)
            {
                lbaResults.Add(Crypto.Decrypt(baEntry, baEntry.Length, intbid, bAlgorithm));
            }
            return lbaResults;
        }
    }
}
